package com.bun.service;

import static com.google.appengine.api.taskqueue.TaskOptions.Builder.withUrl;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.json.JSONArray;
import org.json.JSONObject;

import com.bun.dao.ConfigDao;
import com.bun.vo.Config;
import com.google.appengine.api.memcache.ErrorHandlers;
import com.google.appengine.api.memcache.MemcacheService;
import com.google.appengine.api.memcache.MemcacheServiceFactory;
import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.QueueFactory;



public class IpMonService {
	public boolean hasPhone(){
		boolean hasPhone = false;
		MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService();
		syncCache.setErrorHandler(ErrorHandlers.getConsistentLogAndContinue(Level.INFO));
		syncCache.delete("detailSuccess");
		syncCache.delete("detailFail");
		try {
			Config config = getConfig();
			//String availJSONURL = "https://reserve-au.apple.com/AU/en_AU/reserve/iPhone/availability.json";
			//String storeJSONURL = "https://reserve-au.apple.com/AU/en_AU/reserve/iPhone/stores.json";
			
			String availJSONURL = config.getAvailURL();
			String storeJSONURL = config.getStoreURL();
			String device = config.getDevice();
			String urlReferrer = availJSONURL.replace(".json","");
			System.out.println("urlReferrer:"+urlReferrer);
			
			HashMap<String, String> phoneDetailMap = new HashMap<String, String>();

			List<String> phoneList = new ArrayList<String>();
			
			if(availJSONURL.indexOf("AU")>=0){ // testing only
				phoneDetailMap.put("MG4A2X/A", "16黑");
				phoneDetailMap.put("MGAK2X/A", "16白");
				
				phoneList.add("MG4A2X/A");
				phoneList.add("MGAK2X/A");
				
			}
			if(availJSONURL.indexOf("JP")>=0){ // testing only
				phoneDetailMap.put("MG4E2J/A", "16黑");
				phoneDetailMap.put("MGAC2J/A", "16白");
				
				phoneList.add("MG4E2J/A");
				phoneList.add("MGAC2J/A");
				
			}
			if(availJSONURL.indexOf("GB")>=0){ // testing only
				phoneDetailMap.put("MGAE2B/A", "16黑");
				phoneDetailMap.put("MG4J2B/A", "16白");
				
				phoneList.add("MGAE2B/A");
				phoneList.add("MG4J2B/A");
				
			}
			if(availJSONURL.indexOf("HK")>=0){ 
				if(device.equals("0") || device.equals("2") ){
					phoneDetailMap.put("MGA82ZP/A", "16GB-黑-6P");
					phoneDetailMap.put("MGA92ZP/A", "16GB-白-6P");
					phoneDetailMap.put("MGAA2ZP/A", "16GB-金-6P");
					phoneDetailMap.put("MGAH2ZP/A", "64GB-黑-6P");
					phoneDetailMap.put("MGAJ2ZP/A", "64GB-白-6P");
					phoneDetailMap.put("MGAK2ZP/A", "64GB-金-6P");
					phoneDetailMap.put("MGAC2ZP/A", "128GB-黑-6P");
					phoneDetailMap.put("MGAE2ZP/A", "128GB-白-6P");
					phoneDetailMap.put("MGAF2ZP/A", "128GB-金-6P");
					
					phoneList.add("MGA82ZP/A");
					phoneList.add("MGA92ZP/A");
					phoneList.add("MGAA2ZP/A");
					phoneList.add("MGAH2ZP/A");
					phoneList.add("MGAJ2ZP/A");
					phoneList.add("MGAK2ZP/A");
					phoneList.add("MGAC2ZP/A");
					phoneList.add("MGAE2ZP/A");
					phoneList.add("MGAF2ZP/A");
				}
				if(device.equals("1") || device.equals("2") ){
					phoneDetailMap.put("MG472ZP/A", "16GB-黑-6");
					phoneDetailMap.put("MG482ZP/A", "16GB-白-6");
					phoneDetailMap.put("MG492ZP/A", "16GB-金-6");
					phoneDetailMap.put("MG4F2ZP/A", "64GB-黑-6");
					phoneDetailMap.put("MG4H2ZP/A", "64GB-白-6");
					phoneDetailMap.put("MG4J2ZP/A", "64GB-金-6");
					phoneDetailMap.put("MG4A2ZP/A", "128GB-黑-6");
					phoneDetailMap.put("MG4C2ZP/A", "128GB-白-6");
					phoneDetailMap.put("MG4E2ZP/A", "128GB-金-6");
					
					phoneList.add("MG472ZP/A");
					phoneList.add("MG482ZP/A");
					phoneList.add("MG492ZP/A");
					phoneList.add("MG4F2ZP/A");
					phoneList.add("MG4H2ZP/A");
					phoneList.add("MG4J2ZP/A");
					phoneList.add("MG4A2ZP/A");
					phoneList.add("MG4C2ZP/A");
					phoneList.add("MG4E2ZP/A");
				}
				
				
			}
			
			
			List<String> storeNumnberList = new ArrayList<String>();
			List<String> storeNameList = new ArrayList<String>();
			String reserveURL = "";
			
			HttpURLConnection connection = null;
			URL url = new URL(storeJSONURL);
			System.out.println("AAA:" + storeJSONURL);
			
			connection = (HttpURLConnection) url.openConnection();
			
			connection.setRequestMethod("GET");
			//connection.setRequestProperty("Content-Type", "text/plain; charset=utf-8");
			connection.setRequestProperty("Content-Type", "application/json; charset=utf-8");
			connection.setRequestProperty("Content-Length",	"" + Integer.toString("".getBytes().length));
			connection.setRequestProperty("Content-Language", "en-US");
			connection.setRequestProperty("Referer", urlReferrer);
			//connection.setRequestProperty("Cookie","s_vnum_n2_hk=0%7C1; s_vnum_n2_jp=0%7C1; s_vnum_n2_gb=0%7C1; s_pathLength=ireserve%3D10%2C; s_invisit_n2_au=0; s_vnum_n2_au=0%7C2; s_cc=true; s_fid=448C83E94F64B9EE-110FA0221D876E22; s_orientation=%5B%5BB%5D%5D; s_sq=%5B%5BB%5D%5D; s_ppv=ireserve%2520-%2520availability%2520%2528au%2529%2C48%2C48%2C334%2C; s_orientationHeight=334");
			connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36");
			connection.setUseCaches(false);
			connection.setDoInput(true);
			connection.setDoOutput(true);
			
			System.out.println(connection.getResponseCode());

			//System.out.println("responseCode="+connection.getResponseCode());
			// Send request
			DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
			wr.flush();
			wr.close();
			// Get Response
			InputStream is = connection.getInputStream();
			BufferedReader rd = new BufferedReader(new InputStreamReader(is, "utf-8"));
		    String line;
		    StringBuilder sb = new StringBuilder();
		    while ((line = rd.readLine()) != null) {
		    	System.out.println(line);
		    	sb.append(line);
		    }
		    
		    JSONObject fullStoreJson = new JSONObject(sb.toString());
		    reserveURL = fullStoreJson.getString("reservationURL");
		    //System.out.println(reserveURL);
		    JSONArray storeArrayJson =fullStoreJson.getJSONArray("stores");
		    
		    for(int i=0; i<storeArrayJson.length(); i++){
		    	JSONObject storeDetailJson = storeArrayJson.getJSONObject(i);
		    	storeNumnberList.add(storeDetailJson.getString("storeNumber"));
		    	storeNameList.add(storeDetailJson.getString("storeName"));
		    }
		    
		    
		    
		    //after get the store list, get the phone availablitly list
		    HttpURLConnection connection2 = null;
			URL url2 = new URL(availJSONURL);
			connection2 = (HttpURLConnection) url2.openConnection();
			
			connection2.setRequestMethod("GET");
			connection2.setRequestProperty("Content-Type", "application/json; charset=utf-8");
			connection2.setRequestProperty("Content-Length",	"" + Integer.toString("".getBytes().length));
			connection2.setRequestProperty("Content-Language", "en-US");
			connection2.setRequestProperty("Referer", urlReferrer);
			connection2.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36");
			connection2.setUseCaches(false);
			connection2.setDoInput(true);
			connection2.setDoOutput(true);
			
			System.out.println("responseCode="+connection2.getResponseCode());
			
			// Send request
			DataOutputStream wr2 = new DataOutputStream(connection2.getOutputStream());
			wr2.flush();
			wr2.close();
			// Get Response
			InputStream is2 = connection2.getInputStream();
			BufferedReader rd2 = new BufferedReader(new InputStreamReader(is2, "utf-8"));
		    String line2;
		    StringBuilder sb2 = new StringBuilder();
		    while ((line2 = rd2.readLine()) != null) {
		    	System.out.println(line2);
		    	sb2.append(line2);
		    }
		    
			
		    String detailSuccess = "";
		    String detailFail = "";
		    JSONObject fullPhoneJson = new JSONObject(sb2.toString());
		    for(int i=0; i<storeNumnberList.size(); i++){
		    	//System.out.println(storeNameList.get(i));
		    	JSONObject phoneAvailabilityJson = fullPhoneJson.getJSONObject(storeNumnberList.get(i));
		    	for(int j=0; j<phoneList.size(); j++){
		    		Boolean phoneAvailability = phoneAvailabilityJson.getBoolean(phoneList.get(j));
		    		if(phoneAvailability){
		    			hasPhone = true;
		    			detailSuccess+="<span><a style=\"color:blue;\" target=\"_blank\" href=\""+reserveURL+"\">"+storeNameList.get(i)+"-"+phoneDetailMap.get(phoneList.get(j))+"</a><span><br/>";
		    		}
		    		else{
		    			detailFail+="<span style=\"color:red;\">"+storeNameList.get(i)+"-"+phoneDetailMap.get(phoneList.get(j))+"</span><br/>";
		    		}
		    	}
		    	detailSuccess+="<br/>";
		    	detailFail+="<br/>";
		    }
		    syncCache.put("detailSuccess", detailSuccess);
		    syncCache.put("detailFail", detailFail);
		}
		catch (Exception ex){
			ex.printStackTrace();
			hasPhone = false;
		}
		return hasPhone;
		//
	}
	
	public boolean hasPhone2(){
		boolean hasPhone = false;
		try {
			
			HttpURLConnection connection = null;
			String postData = "ajaxSource=true&_eventId=availability&storeNumber=R409&partNumbers=MGAA2ZP%2FA%2CMGAK2ZP%2FA%2CMGAF2ZP%2FA&selectedContractType=UNLOCKED&p_ie=12f0b72c-5fe8-4fa8-898d-61599bea61fa";

			URL url = new URL("https://reserve-hk.apple.com/HK/zh_HK/reserve/iPhone?execution=e1s3"+"&"+postData);
			
			connection = (HttpURLConnection) url.openConnection();
			
			
			connection.setRequestMethod("POST");
			//connection.setRequestProperty("Content-Type", "text/plain; charset=utf-8");
			connection.setRequestProperty("Content-Type", "application/json; charset=utf-8");
			connection.setRequestProperty("Content-Length",	"" + Integer.toString(postData.getBytes().length));
			connection.setRequestProperty("Content-Language", "en-US");
			connection.setRequestProperty("Referer", "https://reserve-hk.apple.com/HK/zh_HK/reserve/iPhone?execution=e1s3");
			connection.setRequestProperty("Cookie","a0cd230473d569faec6343a0060e1a3077df1e5b=18fe06ab-201f-422c-ab1a-ab9b2d3afc63; pxro=1; dssf=1; dssid2=8a7b4739-9e6e-4509-87fe-b738731072fa; s_vnum_n2_jp=0%7C2; SRVNAME=c4; JSESSIONID=E2EAA1460C2A221AA214D7A3698F88E6; dslang=HK-ZH; ds01_a=2cbc0035b4dd3cd720727c815d31131138d02691ef61e163319d52798bb471a2b07e6d1dbc72fa74c773d2294cdbd4db270626bcee45a25f89c334484c86142a7addb1d7d8e377a1c2ca66b32306c470e580062a585238ac0a65011f1fb540efGZVX; myacinfo=DAWTKNV2001820SZZK8f19dc9f3ec42fc3577ece6c6c2b70e0e6e21646d99982caaf6d6a6565b8b3b101c49da7e7f74d65c6d435d6d29082ca5889d95a0871a90e7b1e7d1c1571163c07de1316c0e5c05ce3702d350aef19d30fc27ff8f4fafca57c57b5276c69d438cdf32364752b61dd0f36785ec602fbe6f4c487b877e299f8795f0356acad9a08ebe9563612146bd5dfdedce1a7c8bde425671a728f89cf6f9b75a4c02d110f4fc06dc8164514b0e379b54c6a19403d0b05464130ed291418be00e90c37c396f906c6cb390cbe0fa09bcc96250c0752a4e9448bbd98cf15ef4c4c97b198c3cd2470433ff0a654b4ca6d7882bc2a5f42a5de7e4d3ef5d2436a0f9f17fc63842d7dMVRYV2; s_invisit_n2_hk=0; s_vnum_n2_hk=3%7C1%2C0%7C8%2C99%7C1%2C20%7C1; s_vnum_n2_us=0|1; s_cc=true; s_orientation=%5B%5BB%5D%5D; s_pathLength=ireserve%3D2%2C; s_sq=%5B%5BB%5D%5D; s_vi=[CS]v1|2A0E27E105194944-6000060180000182[CE]; s_orientationHeight=1443; s_ppv=ireserve%2520-%2520product%2520selection%2520%2528hk%2529%2C100%2C100%2C1443%2C100%3A4%7C200%3A7%7C300%3A7%7C400%3A8%7C500%3A8%7C600%3A8%7C700%3A10%7C800%3A%3E%7C900%3A8%7C1000%3A5%7C1100%3A5%7C1200%3A4%7C1300%3A2%7C1400%3A2; s_fid=4FF155E8869A8A3E-30DC4F582FE19D1F");
			connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36");
			connection.setUseCaches(false);
			connection.setDoInput(true);
			connection.setDoOutput(true);
			
			System.out.println(connection.getResponseCode());

			//System.out.println("responseCode="+connection.getResponseCode());
			// Send request
			DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
			wr.flush();
			wr.close();
			// Get Response
			InputStream is = connection.getInputStream();
			BufferedReader rd = new BufferedReader(new InputStreamReader(is, "utf-8"));
		    String line;
		    StringBuilder sb = new StringBuilder();
		    while ((line = rd.readLine()) != null) {
		    	System.out.println(line);
		    	sb.append(line);
		    }
		}
		catch(Exception ex){
			ex.printStackTrace();
		}
		return hasPhone;
		//
	}
	
	public void sendMail(String subject, String body){
		  Config config = getConfig();
		  Properties props = new Properties();
	        Session session = Session.getDefaultInstance(props, null);

	        String msgBody = body;

	        try {
	        	
	        	if(!config.getReceiver().equals("-")){ // no other receiver
	        		MimeMessage msg = new MimeMessage(session);
	        		if(config.getReceiver().indexOf(",")>=0){ // multiple receiver
	        			String receivers[] = config.getReceiver().split(",");
	        			InternetAddress[] addressTo = new InternetAddress[receivers.length];
	        			for (int i=0; i<receivers.length; i++){
	                        addressTo[i] = new InternetAddress(receivers[i]);
	                        //System.out.println("AAA"+receivers[i]);
	                    }
			            msg.addRecipients(Message.RecipientType.TO, addressTo);
	        		}
	        		else{ // single receiver
	        			msg.addRecipient(Message.RecipientType.TO, new InternetAddress(config.getReceiver()));
                        //System.out.println("BBB"+config.getReceiver());

	        		}

		            msg.setFrom(new InternetAddress(config.getSender()));
		            msg.setSubject(subject);
		            msg.setText(msgBody, "utf-8", "html");
		            Transport.send(msg);
	        	}
	            
	           
	        	MimeMessage msg2 = new MimeMessage(session);
	            msg2.setFrom(new InternetAddress(config.getSender()));
	            //msg.addRecipient(Message.RecipientType.TO, new InternetAddress(config.getReceiver()));
	            msg2.addRecipient(Message.RecipientType.TO, new InternetAddress("admins"));
	            msg2.setSubject(subject);
	            msg2.setText(msgBody, "utf-8", "html");
	            Transport.send(msg2);
	            
	            

	        } catch (AddressException e) {
	        	e.printStackTrace();
	        } catch (MessagingException e) {
	        	e.printStackTrace();
			}
	}
	
	public void updateConfig(String monitor, String sender, String receiver, String smsFrom, String smsTo, String refresh, String device, String availURL, String storeURL){
		ConfigDao configDao = new ConfigDao();
		Config config = new Config();
		config.setMonitor(monitor);
		config.setSender(sender);
		config.setReceiver(receiver);
		config.setSmsFrom(smsFrom);
		config.setSmsTo(smsTo);
		config.setRefresh(refresh);
		config.setDevice(device);
		config.setAvailURL(availURL);
		config.setStoreURL(storeURL);
		configDao.updateConfig(config);
		
		MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService();
		syncCache.setErrorHandler(ErrorHandlers.getConsistentLogAndContinue(Level.INFO));
		syncCache.clearAll();
		
		syncCache.put("monitor", monitor);
		syncCache.put("sender", sender);
		syncCache.put("receiver", receiver);
		syncCache.put("smsFrom", smsFrom);
		syncCache.put("smsTo", smsTo);
		syncCache.put("refresh", refresh);
		syncCache.put("device", device);
		syncCache.put("availURL", availURL);
		syncCache.put("storeURL", storeURL);
		
	}
	
	
	
	public Config getConfig(){
		MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService();
		syncCache.setErrorHandler(ErrorHandlers.getConsistentLogAndContinue(Level.INFO));
		
		String monitor = (String) syncCache.get("monitor");
		String sender = (String) syncCache.get("sender");
		String receiver = (String) syncCache.get("receiver");
		String smsFrom = (String) syncCache.get("smsFrom");
		String smsTo = (String) syncCache.get("smsTo");
		String refresh = (String) syncCache.get("refresh");
		String device = (String) syncCache.get("device");
		String availURL = (String) syncCache.get("availURL");
		String storeURL = (String) syncCache.get("storeURL");
		
		Config config = new Config();
		
		if(monitor == null || sender == null || receiver == null || smsFrom == null || smsTo == null || refresh == null || device == null || availURL == null || storeURL == null){
			ConfigDao configDao = new ConfigDao();
			config = configDao.getConfig();
			syncCache.put("monitor", config.getMonitor());
			syncCache.put("sender", config.getSender());
			syncCache.put("receiver", config.getReceiver());
			syncCache.put("smsFrom", config.getSmsFrom());
			syncCache.put("smsTo", config.getSmsTo());
			syncCache.put("refresh", config.getRefresh());
			syncCache.put("device", config.getDevice());
			syncCache.put("availURL", config.getAvailURL());
			syncCache.put("storeURL", config.getStoreURL());
		}
		else{
			config.setMonitor(monitor);
			config.setSender(sender);
			config.setReceiver(receiver);
			config.setSmsFrom(smsFrom);
			config.setSmsTo(smsTo);
			config.setRefresh(refresh);
			config.setDevice(device);
			config.setAvailURL(availURL);
			config.setStoreURL(storeURL);
		}
		return config;
		
	}
	
	public void addTask(){
		Config config = getConfig();
		String monitor = config.getMonitor();
		String refresh = config.getRefresh();
		
		
		if(monitor.equalsIgnoreCase("T")){
			Queue queue = QueueFactory.getDefaultQueue();
			if(refresh.equals("5")){
				queue.add(withUrl("/ipMon.jsp").countdownMillis(0));
				queue.add(withUrl("/ipMon.jsp").countdownMillis(5000));
				queue.add(withUrl("/ipMon.jsp").countdownMillis(10000));
				queue.add(withUrl("/ipMon.jsp").countdownMillis(15000));
				queue.add(withUrl("/ipMon.jsp").countdownMillis(20000));
				queue.add(withUrl("/ipMon.jsp").countdownMillis(25000));
				queue.add(withUrl("/ipMon.jsp").countdownMillis(30000));
				queue.add(withUrl("/ipMon.jsp").countdownMillis(35000));
				queue.add(withUrl("/ipMon.jsp").countdownMillis(40000));
				queue.add(withUrl("/ipMon.jsp").countdownMillis(45000));
				queue.add(withUrl("/ipMon.jsp").countdownMillis(50000));
				queue.add(withUrl("/ipMon.jsp").countdownMillis(55000));
			}
			else if(refresh.equals("10")){
				queue.add(withUrl("/ipMon.jsp").countdownMillis(0));
				queue.add(withUrl("/ipMon.jsp").countdownMillis(10000));
				queue.add(withUrl("/ipMon.jsp").countdownMillis(20000));
				queue.add(withUrl("/ipMon.jsp").countdownMillis(30000));
				queue.add(withUrl("/ipMon.jsp").countdownMillis(40000));
				queue.add(withUrl("/ipMon.jsp").countdownMillis(50000));
			}
			else if(refresh.equals("30")){
				queue.add(withUrl("/ipMon.jsp").countdownMillis(0));
				queue.add(withUrl("/ipMon.jsp").countdownMillis(30000));
			}
			else if(refresh.equals("60")){
				queue.add(withUrl("/ipMon.jsp").countdownMillis(0));
			}			
		}
	}
	
}
